package org.vectrics.recruiter.struts.admin;

import java.math.BigDecimal;

import javax.servlet.jsp.JspException;

import org.apache.log4j.Category;
import org.apache.struts.action.ActionForm;
import org.vectrics.SystemException;
import org.vectrics.company.Company;
import org.vectrics.domain.Domain;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.history.HistoryProvider;
import org.vectrics.location.Location;
import org.vectrics.provider.CoreServiceLocator;
import org.vectrics.recruiter.RecruitServiceLocator;
import org.vectrics.recruiter.config.RecruitConfig;
import org.vectrics.recruiter.job.Job;
import org.vectrics.recruiter.job.JobClassification;
import org.vectrics.recruiter.job.JobStatusReasonType;
import org.vectrics.recruiter.job.JobStatusType;
import org.vectrics.recruiter.job.JobTerm;
import org.vectrics.recruiter.struts.JobFormBase;
import org.vectrics.recruiter.struts.tag.JobDetailDisplayOptions;
import org.vectrics.struts.Request;
import org.vectrics.struts.UserBufferManager;
import org.vectrics.struts.VectricsActionData;
import org.vectrics.struts.VectricsStrutsAction;
import org.vectrics.user.Person;

public class SaveJobAction extends VectricsStrutsAction {
	public static final long serialVersionUID = 434642223;
    private static Category log = Category.getInstance(SaveJobAction.class);
    public static final String CURRENT_JOB_KEY = "jobId";    
	
    public SaveJobAction() {
    	super();
    }

	public String doExecute(VectricsActionData actionData)	throws JspException {
		Request request = actionData.getRequest();
		ActionForm form = actionData.getForm();	
		Person person = null;
		JobFormBase jobForm = (JobFormBase)form;
		String forwardCode = "success";
		boolean activated = false;
		boolean deactivated = false;
		boolean newJob = false;
		
		if (actionData.wasButtonPressed("cancel") == true) {
			JobDetailDisplayOptions options = new JobDetailDisplayOptions();
			options.setDefaultOptions();
		   	
			JobSearchActionHelper helper = new JobSearchActionHelper();
		    helper.storeDisplayOptions(actionData.getRequest(), options);			
	
		    log.debug("Cancel button pressed.");
		    forwardCode = "cancel";
			if ((jobForm.getJobId() == null) || (jobForm.getJobId().trim().equals(""))) {
				forwardCode = "cancel.new";
			}

		} else {
			ThreadProperties.getSession().clear();
			try {
				person = CoreServiceLocator.getUserAuthService().getAuthorizedPerson(ThreadProperties.getDomain(), request);
			}
			catch (Exception ex) {
				log.error("Exception finding auth user", ex);
				throw new JspException("Exception finding auth user", ex);
			}
	
	        log.debug("execute() called, reading http parameters");
	        Job job = null;
	        
			if ((jobForm.getJobId() == null) || (jobForm.getJobId().trim().equals(""))) {
				log.debug("execute() - creating new job - job id param not passed to this action.");
				
				job = new Job();
	            newJob = true;
				if (log.isDebugEnabled())
	            	log.debug("execute() - new job id = " + job.getId());
			} else {
				log.debug("execute() - attempting to find job.");
				try {
				    Long jobId = new Long(jobForm.getJobId());
					job = RecruitServiceLocator.getJobProvider().findJob(jobId);
				} catch (Exception de) {
					log.error("Could not find job: " + jobForm.getJobId());
					throw new JspException(de);
				}
	            
				if (person == null) {
					throw new JspException("Could not find user logged in.");
				}
	
				if (job == null) {
					log.error("execute() - job ID not found: " + jobForm.getJobId());
				}
			}
			
			JobClassification classification = RecruitServiceLocator.getJobProvider().findJobClassification(jobForm.getClassification());
			job.setClassification(classification);
			
			log.debug("execute() - setting job properties.");
			job.setTitle(jobForm.getTitle());
			job.setDescription(jobForm.getDescription());
			
			
			if (log.isDebugEnabled()) 
			    log.debug("Company = " + jobForm.getCompanyId());
	
			if ((jobForm.getCompanyId() == null) || (jobForm.getCompanyId().trim().length() <= 0)) 
				throw new SystemException("Company ID not specified - every job needs a company");
			else {
				Company company = CoreServiceLocator.getCompanyService().findCompany(
						new Long(jobForm.getCompanyId()));
				job.setCompany(company);
			}
						
			if (job.getCurrentStatus() == null) {
				Domain domain = job.getCompany().getDomain();
				JobStatusType createdStatusType = RecruitServiceLocator.getJobProvider()
					.findJobStatusType(JobStatusType.STATUS_CREATED, domain);
			    JobStatusReasonType defaultCreatedStatusReason 
			    	= RecruitServiceLocator.getJobProvider().findDefaultStatusReason(domain, null, JobStatusType.STATUS_CREATED);
				job.setStatus(createdStatusType, ThreadProperties.getPerson(), defaultCreatedStatusReason);
			}
			
			
			Location location = null;
			if (jobForm.getLocationId() != null)
				location = CoreServiceLocator.getLocationService().findLocation(new Long(jobForm.getLocationId()));
	
			job.setFunction(RecruitServiceLocator.getJobProvider().findFunction(jobForm.getFunctionCode()));
			boolean autoRefId = RecruitConfig.getRecruitInstance().getAutoJobReferenceId(ThreadProperties.getDomain());
			if (autoRefId == false)
				job.setReferenceId(jobForm.getReferenceId());

			if ((jobForm.getTermCode() != null) && (!jobForm.getTermCode().equals(""))) {
				JobTerm term = RecruitServiceLocator.getJobProvider().findJobTermForCode(jobForm.getTermCode());		
				job.setJobTerm(term);				
			} else {
				job.setJobTerm(null);
			}
			
			job.setSalaryType(RecruitServiceLocator.getJobProvider().findJobSalaryType(jobForm.getSalaryType()));
			job.setPayType(RecruitServiceLocator.getJobProvider().findJobPayType(jobForm.getPayType()));
			if ((jobForm.getSalary() != null) && (jobForm.getSalary().length() > 0)) {
				String salaryStr = jobForm.getSalary();
				// Remove any comma's or dollar signs the user put in the salary
				salaryStr = salaryStr.replaceAll(",", "");
				salaryStr = salaryStr.replaceAll("\\$", "");
				job.setSalary(new BigDecimal(salaryStr));
			} else {
				job.setSalary(null);
			}
			if ((jobForm.getSalaryMax() != null) && (jobForm.getSalaryMax().length() > 0)) {
				String salaryMaxStr = jobForm.getSalaryMax();
				// Remove any comma's or dollar signs the user put in the SalaryMax
				salaryMaxStr = salaryMaxStr.replaceAll(",", "");
				salaryMaxStr = salaryMaxStr.replaceAll("\\$", "");
				job.setSalaryMax(new BigDecimal(salaryMaxStr));
			} else {
				job.setSalaryMax(null);
			}
			
			// If max salary is given with no min salary, then swap min and max
			// and just call it THE salary.
			if ((job.getSalaryMax() != null) && (job.getSalary() == null)) {
				job.setSalary(job.getSalaryMax());
				job.setSalaryMax(null);
			}
			if (((job.getSalaryMax() != null)&& (job.getSalary() != null)) && (job.getSalaryMax().equals(job.getSalary()))) {
				job.setSalaryMax(null);
			}
			
			job.setLocation(location);
			job.setSearchWords(jobForm.getSearchWords());
			job.setFeatured(jobForm.getFeatured());
			job.setCompanyInfo(jobForm.getCompanyInfo());
			job.setRequiredSkills(jobForm.getRequiredSkills());
			Long travelPercent = null;
			if (jobForm.getTravelPercent() != null) 
			    travelPercent = new Long(jobForm.getTravelPercent());
			job.setTravelPercent(travelPercent);
			job.setSummary(jobForm.getSummary());
			job.setWorkSchedule(jobForm.getWorkSchedule());
			job.setEducation(jobForm.getEducation());
			job.setNumberOfPositions(Integer.valueOf(jobForm.getNumberOfPositions()));
			job.setNumberOfReceivedResumes(new Integer(jobForm.getNumberOfReceivedResumes()));
			
			log.debug("execute() - setting job roles.");
			if ((jobForm.getPrimaryRecruiter() == null) || (jobForm.getPrimaryRecruiter().trim().length() == 0)) {
				job.setPrimaryRecruiter(null);
			} else {
				job.setPrimaryRecruiter(CoreServiceLocator.getPersonService().findPersonById(new Long(jobForm.getPrimaryRecruiter())));
			}
			if ((jobForm.getSecondaryRecruiter() == null) 
					|| (jobForm.getSecondaryRecruiter().trim().length() == 0)) {
				job.setSecondaryRecruiter(null);
			} else {
				job.setSecondaryRecruiter(CoreServiceLocator.getPersonService().findPersonById(new Long(jobForm.getSecondaryRecruiter())));
			}

			if ((jobForm.getHiringManager() == null) || (jobForm.getHiringManager().trim().length() == 0)) {
			    job.setHiringManager(actionData.getAuthPerson());
			} else {
				Person hiringManager = CoreServiceLocator.getPersonService().findPersonById(new Long(jobForm.getHiringManager())); 
				job.setHiringManager(hiringManager);
			}
			if ((jobForm.getReferenceId() != null) && (jobForm.getReferenceId().trim().length() > 0)) {
				job.setReferenceId(jobForm.getReferenceId());
			} else {
				RecruitServiceLocator.getJobProvider().findNextJobReferenceCode(job.getCompany().getDomain(), job);
			}
			
			if ((jobForm.getRequester() == null) || (jobForm.getRequester().trim().length() == 0)) {
			    job.setRequester(actionData.getAuthPerson());
			} else {
				Person requester = CoreServiceLocator.getPersonService().findPersonById(new Long(jobForm.getRequester())); 
				job.setRequester(requester);
			}
			
			log.debug("execute() - finished saving job info.");
			RecruitServiceLocator.getJobProvider().updateJob(job);
			ThreadProperties.forcedCommit();

			jobForm.setJobId(job.getId().toString());
			request.setAttribute("job", job);
			request.setAttribute("jobId", job.getId().toString());
			
			try {
				if (activated) {
					HistoryProvider.getInstance().createHistory(Job.OBJECT_TYPE, job.getId().toString(), 
							"job_activate", 
					        person, "Activated Job");
				}
				if (deactivated) {
					HistoryProvider.getInstance().createHistory(Job.OBJECT_TYPE, job.getId().toString(), 
							"job_deactivate", 
					        person, "Deactivated Job");
				}
				ThreadProperties.forcedCommit();
			}
			catch (Exception de) {
				log.error("Exception recording activation history", de);
			}
			
			UserBufferManager bufferManager = new UserBufferManager();	
		    bufferManager.addBufferedObject(request, job);
		}
		
		
		ThreadProperties.forcedCommit();
		return (forwardCode);
    }
}
